"use strict";
const Generator = require("yeoman-generator");
const chalk = require("chalk");
const yosay = require("yosay");
const axios = require("axios");
const codegen = require("../codegen");
const _ = require("lodash");
const util = require("../util");

module.exports = class extends Generator {
  /**
   * 获取当前项目状态，获取基本配置参数等
   */
  initianlizing() {
    this.log("initianlizing function");
  }

  /**
   * 调用inquire方法获取用户输入,向用户展示交互式问题收集关键参数
   * @returns {Promise|PromiseLike<any>|Promise<any>}
   */
  prompting() {
    // Have Yeoman greet the user.
    this.log(
      yosay(
        `Welcome to the funkadelic ${chalk.red(
          "generator-swagger-ts"
        )} generator!`
      )
    );

    const prompts = [
      {
        type: "input",
        name: "swaggerUrl",
        message: "please input swagger url",
        default: "http://127.0.0.1:8080/swagger-ui.html"
      },
      {
        type: "input",
        name: "className",
        message: "please enter class Name of the generated API",
        default: "API"
      },
      {
        type: "list",
        name: "type",
        message: "please choose generated API type , js or typescript",
        choices: [
          {
            name: "typescript",
            value: "typescript"
          },
          {
            name: "javascript",
            value: "js"
          }
        ]
      },
      {
        type: "input",
        name: "outPutFile",
        message: "Please enter the API file name",
        default: "api.ts"
      },
      {
        type: "input",
        name: "name",
        message: "Please enter your name",
        default: "mmyhs"
      },
      {
        type: "input",
        name: "email",
        message: "Please enter your email",
        default: "mmyhs@xxx.com"
      }
    ];

    return this.prompt(prompts).then(props => {
      // To access props later use this.props.someAnswer;
      this.props = props;
    });
  }

  /**
   * 保存配置相关信息且生成配置文件（名称多为'.'开头的配置文件,例如.editorconfig）
   */
  configuring() {
    this.log("configuring function");
  }

  /**
   * 未匹配任何生命周期方法的非私有方法均在此环节*自动*执行
   */
  default() {
    this.log("default function");
  }

  /**
   * 执行文件写操作，即项目文件写入文件系统中
   */
  writing() {
    const swaggerUrl = this.props.swaggerUrl.replace(
      "swagger-ui.html",
      "v2/api-docs"
    );
    const { outPutFile, className, name, email } = this.props;
    const isTypescript = this.props.type === "typescript";
    axios.get(swaggerUrl).then(res => {
      if (res.status === 200) {
        const swagger = res.data;
        const swaggerData = codegen.getViewForSwagger(swagger);
        let data = _.merge(swaggerData, {
          className,
          creatorInfo: { name, email },
          createDateTime: util.format()
        });
        if (isTypescript) {
          this.log("generator ts");
          this.fs.copyTpl(
            this.templatePath("api-ts.ejs"),
            this.destinationPath(outPutFile),
            data
          );
          const dtsSegments = outPutFile.split(".");
          dtsSegments.splice(dtsSegments.length - 1, 0, ".d.");
          this.fs.copyTpl(
            this.templatePath("ts.ejs"),
            this.destinationPath(dtsSegments.join("")),
            data
          );
        } else {
          this.log("generator js");
          const dtsSegments = outPutFile.split(".");
          const extension = dtsSegments.splice(dtsSegments.length - 1, 1);
          data = _.merge(data, {
            outPutVariableFile: dtsSegments.join(".") + "-variable." + extension
          });
          this.fs.copyTpl(
            this.templatePath("api-js.ejs"),
            this.destinationPath(outPutFile),
            data
          );
          this.fs.copyTpl(
            this.templatePath("js.ejs"),
            this.destinationPath(data.outPutVariableFile),
            data
          );
        }
      }
    });
  }

  /**
   * 处理冲突(内部调用，一般不用处理）
   */
  conflicts() {}

  /**
   * 执行安装操作，需调用 this.installDependencies 方法
   */
  install() {
    // This.installDependencies();
  }

  /**
   * 结束动作，例如清屏，输出结束信息，say GoodBye等等
   */
  end() {}
};
